﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace Tradex.ComponentModel {
    
    /// <summary>
    /// The base class for all objects that have a Key to identify them. Suppoprts basic databinding
    /// so the object can be updated. Normal usage is to have an implementing subclass that exposes
    /// read only properties with status property groups.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Serializable ()]
    public class KeyedObject<T> :
        INotifyPropertyChanged
        where
        T : class
    {

        /// <summary>
        /// COnstructor taking the object's key as parameter.
        /// </summary>
        /// <param name="key"></param>
        protected KeyedObject (T key) {
            Key = key;
        }

        /// <summary>
        /// The OnPropertyChanged method trows the PropertyChanged event handler if reasonable. This overload does not set
        /// or compare values, and should thus only be used to throw the PropertyChanged event for secondary / computed properties.
        /// </summary>
        /// <param name="property"></param>
        protected void OnPropertyChanged(string property) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        /// <summary>
        /// The OnPropetyChanged event handler. it is programmed in such a way to not throw an event if
        /// old and new value are identical, and otherwise be usable in only one code line.
        /// </summary>
        /// <typeparam name="TParameter"></typeparam>
        /// <param name="property"></param>
        /// <param name="oldValue"></param>
        /// <param name="newValue"></param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045")]
        protected void OnPropertyChanged<TParameter>(string property, ref TParameter oldValue, TParameter newValue) {
            if (!System.Object.Equals(oldValue, newValue)) {
                oldValue = newValue;
                OnPropertyChanged(property);
            }
            return;
        }

        /// <summary>
        /// Gets the key of the object.
        /// </summary>
        public T Key { get; private set; }

        /// <inheritdoc />
        public event PropertyChangedEventHandler PropertyChanged;

    }

}
